package com.xxx3biji;


import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * stream的终止操作
 */

public class TestStreamAPI03 {

//    List<Employee> emps = Arrays.asList(
//            new Employee(101, "sss", 18, 1.01, Employee.STATUS.MARRIED),
//            new Employee(102, "abc", 59, 2.22, Employee.STATUS.SINGLE),
//            new Employee(103, "abc", 38, 3.33, Employee.STATUS.MARRIED),
//            new Employee(104, "sss", 10, 4.44, Employee.STATUS.MARRIED)
//    );
    List<Employee> emps = new ArrayList<>();

    //去重
    public  <E> List<E> getDuplicateElements(List<E> list) {
        return list.stream()
                .collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b))
                .entrySet().stream()
                .filter(entry -> entry.getValue() > 1)
                .map(entry -> entry.getKey())
                .collect(Collectors.toList());
    }

    @Test
    public void test0111() {
        List<String> collect = emps.stream().map(Employee::getName).collect(Collectors.toList());
        List<String> repeatList = collect.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()))
                .entrySet().stream().filter(e -> e.getValue() > 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());
        System.out.println(repeatList.toString());
        System.out.println(repeatList.size());
    }

    /**
     * 查找与匹配
     * allMatch--检查是否匹配所有元素
     * anyMatch--检查是否至少匹配一个元素
     * noneMatch--检查是否没有匹配所有元素
     * findFirst--返回第一个元素
     * count--返回流中元素的总个数
     * max--返回流中最大值
     * min--返回流中最小值
     */
    @Test
    public void test01() {
        boolean b1 = emps.stream()
                .allMatch(employee -> employee.getStatus().equals(Employee.STATUS.MARRIED));
        System.out.println(b1);

        boolean b2 = emps.stream()
                .anyMatch(employee -> employee.getStatus().equals(Employee.STATUS.MARRIED));
        System.out.println(b2);

        boolean b3 = emps.stream()
                .noneMatch(employee -> employee.getStatus().equals(Employee.STATUS.MARRIED));
        System.out.println(b3);

        Optional<Employee> op = emps.stream()
                .sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();
        System.out.println(op.get());

    }

    /**
     * 规约
     * reduce(T identity, BinaryOperator<T> accumulator) --> T
     * reduce(BinaryOperator<T> accumulator) --> Optional<T>
     * <p>
     * --可以将流中元素反复结合起来，得到一个值。
     */
    @Test
    public void test02() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list.stream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(sum);

    }

    /**
     * 收集
     * collect--将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
     */

    //分区
    @Test
    public void test05() {
        Map<Boolean, List<Employee>> collect = emps.stream()
                .collect(Collectors.partitioningBy(e ->
                        e.getSalary() > 6000
                ));
        System.out.println(collect);

    }

    //综合
    @Test
    public void test06() {
        DoubleSummaryStatistics zh = emps.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(zh.getAverage());
        System.out.println(zh.getCount());
        System.out.println(zh.getSum());
        System.out.println(zh.getMax());
        System.out.println(zh.getMin());
    }

    //拼接
    @Test
    public void test07() {
        String str = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",", "[", "]"));
        System.out.println(str);

    }

    //分组
    @Test
    public void test04() {
        Map<Employee.STATUS, List<Employee>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);

        //多级分组
        Map<Employee.STATUS, Map<String, List<Employee>>> collect = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
            if (e.getAge() <= 35) {
                return "青年";
            } else if (e.getAge() <= 50) {
                return "中年";
            } else {
                return "老年";
            }
        })));
        System.out.println(collect);

    }

    @Test
    public void test03() {
//        List<String> list = emps.stream()
//                .map(Employee::getName)
//                .collect(Collectors.toList());
//        System.out.println(list);
//        System.out.println("-------------------");
//        Set<String> hashSet = emps.stream()
//                .map(Employee::getName)
//                .collect(Collectors.toCollection(LinkedHashSet::new));
//        System.out.println(hashSet);
//        System.out.println("===================");

        //总和
        Double reduce = emps.stream()
                .map(employee -> employee.getSalary())
                .reduce((double) 0, (x, y) -> x + y);
        System.out.println(reduce);

        double sum = emps.stream().mapToDouble(Employee::getSalary).sum();
        System.out.println(sum);

    }
}
